package com.yupi.yupicturebackend.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.yupicturebackend.mapper.AIGenerationTaskMapper;
import com.yupi.yupicturebackend.model.dto.ai.AIGenerationConfig;
import com.yupi.yupicturebackend.model.dto.ai.AIGenerationResult;
import com.yupi.yupicturebackend.model.entity.AIGenerationTask;
import com.yupi.yupicturebackend.service.AIGenerationTaskService;
import com.yupi.yupicturebackend.utils.AIImageGenerationUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * AI图片生成任务服务实现
 *
 * @author yupi
 */
@Slf4j
@Service
public class AIGenerationTaskServiceImpl extends ServiceImpl<AIGenerationTaskMapper, AIGenerationTask> 
        implements AIGenerationTaskService {

    @Resource
    private AIGenerationTaskMapper aiGenerationTaskMapper;

    @Override
    public String createGenerationTask(String prompt, AIGenerationConfig config, Long userId) {
        String taskId = IdUtil.fastSimpleUUID();
        
        AIGenerationTask task = new AIGenerationTask();
        task.setTaskId(taskId);
        task.setUserId(userId);
        task.setPrompt(prompt);
        task.setNegativePrompt(config.getNegativePrompt());
        task.setModel(config.getModel());
        task.setWidth(config.getWidth());
        task.setHeight(config.getHeight());
        task.setNumImages(config.getNumImages());
        task.setCfgScale(config.getCfgScale());
        task.setSteps(config.getSteps());
        task.setSeed(config.getSeed());
        task.setStylePreset(config.getStylePreset());
        task.setSampler(config.getSampler());
        task.setStatus("pending");
        task.setCreateTime(new Date());
        task.setUpdateTime(new Date());
        
        // 保存扩展配置
        task.setExtendConfig(JSONUtil.toJsonStr(config));
        
        this.save(task);
        
        log.info("创建AI生成任务成功: taskId={}, userId={}", taskId, userId);
        return taskId;
    }

    @Override
    public AIGenerationResult executeGeneration(String taskId) {
        AIGenerationTask task = this.getOne(new QueryWrapper<AIGenerationTask>()
                .eq("taskId", taskId));
        
        if (task == null) {
            log.error("任务不存在: taskId={}", taskId);
            return null;
        }
        
        try {
            // 更新任务状态为处理中
            task.setStatus("processing");
            task.setUpdateTime(new Date());
            this.updateById(task);
            
            // 构建生成配置
            AIGenerationConfig config = JSONUtil.toBean(task.getExtendConfig(), AIGenerationConfig.class);
            
            // 执行AI生成
            long startTime = System.currentTimeMillis();
            AIGenerationResult result = AIImageGenerationUtils.textToImage(task.getPrompt(), config);
            long duration = System.currentTimeMillis() - startTime;
            
            // 更新任务结果
            if (result.getSuccess()) {
                task.setStatus("completed");
                task.setResultUrls(JSONUtil.toJsonStr(result.getImageUrls()));
                task.setQualityScore(result.getQualityScore());
                task.setContentSafe(result.getContentSafe());
                task.setCost(result.getCost());
            } else {
                task.setStatus("failed");
                task.setErrorMessage(result.getErrorMessage());
            }
            
            task.setDuration(duration);
            task.setUpdateTime(new Date());
            this.updateById(task);
            
            log.info("AI生成任务完成: taskId={}, status={}", taskId, task.getStatus());
            return result;
            
        } catch (Exception e) {
            log.error("AI生成任务执行失败: taskId={}", taskId, e);
            
            // 更新任务状态为失败
            task.setStatus("failed");
            task.setErrorMessage(e.getMessage());
            task.setUpdateTime(new Date());
            this.updateById(task);
            
            return null;
        }
    }

    @Override
    public boolean updateTaskStatus(String taskId, String status, AIGenerationResult result) {
        AIGenerationTask task = this.getOne(new QueryWrapper<AIGenerationTask>()
                .eq("taskId", taskId));
        
        if (task == null) {
            return false;
        }
        
        task.setStatus(status);
        task.setUpdateTime(new Date());
        
        if (result != null) {
            if (result.getSuccess()) {
                task.setResultUrls(JSONUtil.toJsonStr(result.getImageUrls()));
                task.setQualityScore(result.getQualityScore());
                task.setContentSafe(result.getContentSafe());
                task.setCost(result.getCost());
            } else {
                task.setErrorMessage(result.getErrorMessage());
            }
        }
        
        return this.updateById(task);
    }

    @Override
    public List<AIGenerationTask> getUserTasks(Long userId, Integer limit) {
        return aiGenerationTaskMapper.selectByUserId(userId, limit != null ? limit : 20);
    }

    @Override
    public List<AIGenerationTask> getPendingTasks(Integer limit) {
        return aiGenerationTaskMapper.selectByStatus("pending", limit != null ? limit : 10);
    }

    @Override
    public Map<String, Object> getUserStatistics(Long userId) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总任务数
        Long totalTasks = aiGenerationTaskMapper.countByUserId(userId);
        statistics.put("totalTasks", totalTasks);
        
        // 成功任务数
        Long completedTasks = this.count(new QueryWrapper<AIGenerationTask>()
                .eq("userId", userId)
                .eq("status", "completed"));
        statistics.put("completedTasks", completedTasks);
        
        // 成功率
        double successRate = totalTasks > 0 ? (double) completedTasks / totalTasks : 0;
        statistics.put("successRate", successRate);
        
        // 最近使用的模型
        List<String> recentModels = aiGenerationTaskMapper.selectRecentModelsByUserId(userId, 5);
        statistics.put("recentModels", recentModels);
        
        // 平均质量分数
        Double avgQualityScore = this.list(new QueryWrapper<AIGenerationTask>()
                .eq("userId", userId)
                .eq("status", "completed")
                .isNotNull("qualityScore"))
                .stream()
                .mapToDouble(AIGenerationTask::getQualityScore)
                .average()
                .orElse(0.0);
        statistics.put("avgQualityScore", avgQualityScore);
        
        return statistics;
    }

    @Override
    public List<Map<String, Object>> getPopularPrompts(Integer limit) {
        return aiGenerationTaskMapper.selectPopularPrompts(limit != null ? limit : 10);
    }

    @Override
    public AIGenerationConfig getRecommendedConfig(Long userId) {
        // 基于用户历史生成记录推荐配置
        List<AIGenerationTask> recentTasks = this.getUserTasks(userId, 10);
        
        AIGenerationConfig recommendedConfig = new AIGenerationConfig();
        
        if (!recentTasks.isEmpty()) {
            // 统计最常用的配置
            Map<String, Long> modelCount = recentTasks.stream()
                    .collect(Collectors.groupingBy(AIGenerationTask::getModel, Collectors.counting()));
            
            String mostUsedModel = modelCount.entrySet().stream()
                    .max(Map.Entry.comparingByValue())
                    .map(Map.Entry::getKey)
                    .orElse("stable-diffusion");
            
            recommendedConfig.setModel(mostUsedModel);
            
            // 计算平均配置参数
            OptionalDouble avgCfgScale = recentTasks.stream()
                    .filter(task -> task.getCfgScale() != null)
                    .mapToDouble(AIGenerationTask::getCfgScale)
                    .average();
            
            if (avgCfgScale.isPresent()) {
                recommendedConfig.setCfgScale(avgCfgScale.getAsDouble());
            }
            
            OptionalDouble avgSteps = recentTasks.stream()
                    .filter(task -> task.getSteps() != null)
                    .mapToDouble(AIGenerationTask::getSteps)
                    .average();
            
            if (avgSteps.isPresent()) {
                recommendedConfig.setSteps((int) avgSteps.getAsDouble());
            }
        }
        
        return recommendedConfig;
    }

    @Override
    public List<String> batchGenerate(List<String> prompts, AIGenerationConfig config, Long userId) {
        List<String> taskIds = new ArrayList<>();
        
        for (String prompt : prompts) {
            String taskId = this.createGenerationTask(prompt, config, userId);
            taskIds.add(taskId);
        }
        
        log.info("批量创建AI生成任务: count={}, userId={}", prompts.size(), userId);
        return taskIds;
    }

    @Override
    public boolean cancelTask(String taskId, Long userId) {
        AIGenerationTask task = this.getOne(new QueryWrapper<AIGenerationTask>()
                .eq("taskId", taskId)
                .eq("userId", userId));
        
        if (task == null || !"pending".equals(task.getStatus())) {
            return false;
        }
        
        task.setStatus("cancelled");
        task.setUpdateTime(new Date());
        
        return this.updateById(task);
    }

    @Override
    public String regenerate(String taskId, Long userId) {
        AIGenerationTask originalTask = this.getOne(new QueryWrapper<AIGenerationTask>()
                .eq("taskId", taskId)
                .eq("userId", userId));
        
        if (originalTask == null) {
            return null;
        }
        
        // 使用原任务的配置创建新任务
        AIGenerationConfig config = JSONUtil.toBean(originalTask.getExtendConfig(), AIGenerationConfig.class);
        return this.createGenerationTask(originalTask.getPrompt(), config, userId);
    }

    @Override
    public Map<String, Object> getGenerationHistory(Long userId, Integer page, Integer size) {
        // 实现分页查询历史记录
        Map<String, Object> result = new HashMap<>();
        
        int offset = (page - 1) * size;
        List<AIGenerationTask> tasks = this.list(new QueryWrapper<AIGenerationTask>()
                .eq("userId", userId)
                .orderByDesc("createTime")
                .last("LIMIT " + offset + ", " + size));
        
        Long total = this.count(new QueryWrapper<AIGenerationTask>()
                .eq("userId", userId));
        
        result.put("tasks", tasks);
        result.put("total", total);
        result.put("page", page);
        result.put("size", size);
        result.put("totalPages", (total + size - 1) / size);
        
        return result;
    }

    @Override
    public String exportResults(List<String> taskIds, Long userId, String format) {
        // 实现结果导出功能
        List<AIGenerationTask> tasks = this.list(new QueryWrapper<AIGenerationTask>()
                .in("taskId", taskIds)
                .eq("userId", userId)
                .eq("status", "completed"));
        
        // 这里应该实现具体的导出逻辑
        // 返回导出文件的URL
        String exportUrl = "https://example.com/exports/" + IdUtil.fastSimpleUUID() + "." + format;
        
        log.info("导出AI生成结果: taskCount={}, userId={}, format={}", tasks.size(), userId, format);
        return exportUrl;
    }
}
